# python学习 至此开始
# 学习日期: 2023/8/17 14:48
# 学习者: 任磊

"""
游戏名称：smallWarGame
作者：任磊
完成日期：2023.8.20
类型：2D像素射击小游戏
描述：主要为 Python 中 pygame 的练习应用，完成的功能类包括，主游戏类，角色类，特效类，道具类，字幕类，音效类，ai类
    玩法为创建角色，获取道具，击败所有敌对立场角色即为获胜

待优化：角色图片细节，敌人种类，敌人攻击方式，各类的方法数量较少

"""

import pygame
import time
import random


# 主游戏类
class MainGame(object):
    def __init__(self):
        pass

    # 游戏版本
    game_version = "1.00"
    # 游戏窗口相关参数
    window = None
    SCREEN_HEIGHT = 1000
    SCREEN_WIDTH = 1700
    COLOR_WHITE = [255, 255, 255]
    COLOR_BLACK = [0, 0, 0]
    BACKGROUND_COLOR = pygame.Color(COLOR_WHITE)
    # 游戏参数
    # 信息显示刷新率
    update_output_time = 0.01
    last_apply_time = None
    now_apply_time = None
    # 游戏时长参数
    Max_time = 3600  # 1 个小时
    start_time = None
    end_time = None
    mid_time = None
    # 最大速度
    MAX_SPEED = 17
    # 障碍物参数
    barrier_number = 8
    barrier_list = []
    # 敌对角色参数
    enemy_number = 10
    enemy_list = []
    # 中立角色参数
    stranger_number = 5
    stranger_list = []
    # 道具参数
    props_number = 5
    props_list = []
    props_update_time = 60
    # 友好角色参数
    friend_number = 5
    friend_list = []
    # 我方角色参数
    me = None
    me_left = SCREEN_WIDTH/2  # 初始生成角色的横向位置
    me_top = SCREEN_HEIGHT/2  # 初始生成角色的纵向位置
    fail_time = 0
    max_bullet = 4
    bullet_list = []
    bullet_number = 30
    # 全体对象列表(不包含特效，子弹)
    all_list = []
    # 字幕列表
    text_list = []
    # 背景音乐参数
    background_mid_time = None
    background_music_between_time = 1

    # 启动游戏的方法
    def start_game(self):
        # 游戏开始时间记录
        MainGame.start_time = time.time()
        # 初始化显示模块
        pygame.display.init()
        # 创建窗口
        MainGame.window = pygame.display.set_mode([MainGame.SCREEN_WIDTH, MainGame.SCREEN_HEIGHT])
        # 创建标题
        pygame.display.set_caption('smallWarGame' + MainGame.game_version)
        # 创建障碍物群
        MainGame().create_all_barrier()
        # 创建全部敌人
        MainGame().create_all_enemy()
        # 创建全部中立方
        MainGame().create_all_strange()
        # 创建全部道具
        MainGame().create_all_props()
        # 创建我方
        MainGame().create_my()
        # 创建初始字幕
        Text.base_text()
        # 创建全对象列表
        MainGame.all_list = MainGame.stranger_list + MainGame.enemy_list + MainGame.barrier_list + MainGame.friend_list
        # 启用游戏开始背景音效
        Music.background_music_start()
        # 游戏开始
        while True:
            # 给窗口完成一个颜色填充
            MainGame.window.fill(MainGame.BACKGROUND_COLOR)
            # 导入背景图片
            MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\background_photo_1.png"), [0, 0])
            # 窗口中持续显示障碍物群
            MainGame().show_all_barrier()
            # 窗口中持续显示全部方
            MainGame().show_all_enemy()
            MainGame().show_all_stranger()
            MainGame().show_all_props()
            # 持续显示字幕
            Text.blit_text()
            # 在循环中持续获取事件
            self.during_event()
            # 持续显示我方
            MainGame.show_my()
            # 我方移动方法调用
            if MainGame.me.condition == "live" and not MainGame.me.stop:
                # 调用移动方法
                MainGame.me.move()
                # 调用碰撞检测方法
                MainGame.me.collision_detection()
                MainGame.me.me_crash_other()
                MainGame.me.get_props()
            # 调用刷新显示主角生命值的方法
            Text.update_text("当前生命值剩余:{}".format(MainGame.me.hp), 5, 5)
            # 刷新敌对角色显示数量
            Text.update_text("当前敌对角色剩余:{}".format(len(MainGame.enemy_list)), 5, 30)
            # 刷新子弹剩余显示
            Text.update_text("当前子弹剩余:{}".format(MainGame.bullet_number), 5, 55)
            # 刷新子弹
            Animation.update_bullet()
            # 调用判断刷新道具的方法
            MainGame.refresh_props(False)  # 启用随机刷新道具的方法
            time.sleep(0.01)
            # 使窗口持续刷新
            pygame.display.flip()
            # 实时记录游戏时间
            MainGame.end_time = time.time()
            # 游戏时长监测
            if MainGame.end_time - MainGame.start_time > MainGame.background_music_between_time * 121:
                # 背景音乐播放
                Music.background_music()
                MainGame.background_music_between_time += 1
                if MainGame.end_time - MainGame.start_time > MainGame.Max_time:
                    MainGame.end_game("other")
            # 全列表刷新
            for item in MainGame.all_list:
                if item.condition != "live":
                    MainGame.all_list.remove(item)
            # 游戏结束判断
            if len(MainGame.enemy_list) == 0:
                MainGame.end_game("victory")

    # 游戏开始后 获取操作的方法
    def during_event(self):
        # 获取事件
        event_list = pygame.event.get()
        # 判断事件并处理
        for event in event_list:
            # 点击退出的方法
            if event.type == pygame.QUIT:
                self.end_game('other')
                # 具体按键判断并处理
            elif event.type == pygame.KEYDOWN:
                if MainGame.me.condition == "live":
                    # 移动方向判断
                    if event.key == pygame.K_LEFT:
                        MainGame.me.direction = 'L'
                        MainGame.me.stop = False
                    elif event.key == pygame.K_RIGHT:
                        MainGame.me.direction = 'R'
                        MainGame.me.stop = False
                    elif event.key == pygame.K_UP:
                        MainGame.me.direction = 'U'
                        MainGame.me.stop = False
                    elif event.key == pygame.K_DOWN:
                        MainGame.me.direction = 'D'
                        MainGame.me.stop = False
                    # 攻击判断
                    elif event.key == pygame.K_SPACE:
                        MainGame.me.attack_display()
                # 判断复活
                elif event.key == pygame.K_ESCAPE:
                    MainGame.relive_me()
            elif event.type == pygame.KEYUP:
                # 判断按键，修改移动开关
                if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                   MainGame.me.stop = True
            else:
                pass

    # 生成障碍物群的方法
    @staticmethod
    def create_all_barrier():
        for i in range(1, MainGame.barrier_number + 1):
            barrier = Barrier(i * 54, MainGame.SCREEN_HEIGHT/4)
            barrier.create("sandbag")
            MainGame.barrier_list.append(barrier)
        for i in range(1, MainGame.barrier_number + 1):
            barrier = Barrier(MainGame.SCREEN_WIDTH/2, i * 54)
            barrier.create("stone")
            MainGame.barrier_list.append(barrier)

    # 显示全部障碍物群的方法
    @staticmethod
    def show_all_barrier():
        # 判断列表非空
        if len(MainGame.barrier_list) != 0:
            for barrier in MainGame.barrier_list:
                # 判断障碍物状态
                if barrier.condition == "live":
                    # 添加至窗口
                    barrier.display()
                else:
                    # 从列表中移除
                    MainGame.barrier_list.remove(barrier)
        else:
            pass

    # 创建全部敌方的方法
    @staticmethod
    def create_all_enemy():
        for i in range(1, MainGame.enemy_number + 1):
            enemy = Person(i * 20, MainGame.SCREEN_HEIGHT/2)
            enemy.option = "enemy"
            enemy.create("zombie")  # 备份为 zombie
            # 随机赋予智能
            num = random.randint(1, 100)
            if num < 40:  # 备份 40
                enemy.ai = True
            MainGame.enemy_list.append(enemy)

    # 显示全部敌方的方法
    @staticmethod
    def show_all_enemy():
        # 判断列表非空
        if len(MainGame.enemy_list) != 0:
            for enemy in MainGame.enemy_list:
                # 判断敌人存活状态
                if enemy.condition == "live":
                    # 判断敌方是否碰到主角
                    enemy.collision_detection()
                    if MainGame.me.condition == "live":
                        if pygame.sprite.collide_rect(enemy, MainGame.me):
                            Person.attack(enemy, MainGame.me)
                            enemy.stay()
                        # 判断是随机移动还是智能寻路
                        elif enemy.ai is True:
                            Ai_function.ai_way_to_other(enemy, MainGame.me)
                        else:
                            enemy.random_move()
                    else:
                        enemy.random_move()
                    enemy.display()
                else:
                    # 移除
                    MainGame.enemy_list.remove(enemy)
        else:
            pass

    # 创建全部中立方的方法
    @staticmethod
    def create_all_strange():
        for i in range(1, MainGame.stranger_number + 1):
            stranger = Person(i * 20, MainGame.SCREEN_HEIGHT - 55)
            stranger.option = "stranger"
            stranger.create("people")
            MainGame.stranger_list.append(stranger)

    # 显示全部中立方的方法
    @staticmethod
    def show_all_stranger():
        # 判断列表非空
        if len(MainGame.stranger_list) != 0:
            for stranger in MainGame.stranger_list:
                # 判断存活状态
                if stranger.condition == "live":
                    # 判断是否碰到主角
                    stranger.collision_detection()
                    if MainGame.me.condition == "live":
                        if pygame.sprite.collide_rect(stranger, MainGame.me):
                            stranger.stay()
                        # 判断是随机移动还是智能寻路
                        elif stranger.ai is True:
                            Ai_function.ai_way_to_other(stranger, MainGame.me)
                        else:
                            stranger.random_move()
                    else:
                        stranger.random_move()
                    stranger.display()
                else:
                    # 移除
                    MainGame.stranger_list.remove(stranger)
        else:
            pass

    # 创建全部道具的方法
    @staticmethod
    def create_all_props():
        for i in range(1, MainGame.props_number + 1):
            props = Props(i * 70, MainGame.SCREEN_HEIGHT/1.5)
            # 分配生成道具的参数
            flag = random.randint(1, 100)
            if flag <= 40:
                props.create_props("bullet_box")
            else:
                props.create_props("medikit")
                # 加入道具列表中
            MainGame.props_list.append(props)

    # 持续展示全部道具的方法
    @staticmethod
    def show_all_props():
        # 判断道具列表非空
        if len(MainGame.props_list) != 0:
            for props in MainGame.props_list:
                # 判断道具状态
                if props.condition == "live":
                    # 将道具展示到窗口中
                    MainGame.window.blit(props.image, props.rect)
                else:
                    # 移除道具
                    MainGame.props_list.remove(props)

    # 道具刷新方法
    @staticmethod
    def refresh_props(flag):
        # 判断道具数量
        if len(MainGame.props_list) < MainGame.props_number:
            # 判断刷新状态
            if flag is False:
                # 随机刷新
                # 判断刷新间隔
                if MainGame.mid_time is None:
                    # 随机刷新位置
                    if len(MainGame.barrier_list) != 0:
                        while True:
                            num = 0
                            # 创建道具
                            props = Props(random.randint(1, MainGame.SCREEN_WIDTH - 55), random.randint(100, MainGame.SCREEN_HEIGHT - 55))
                            for barrier in MainGame.barrier_list:
                                # 判断道具位置是否与障碍物位置重叠
                                if not pygame.sprite.collide_rect(props, barrier):
                                    num += 1
                            if num == len(MainGame.barrier_list):
                                break
                    else:
                        props = Props(random.randint(1, MainGame.SCREEN_WIDTH - 55), random.randint(100, MainGame.SCREEN_HEIGHT - 55))
                    # 随机刷新道具
                    num = random.randint(1, 100)
                    if num <= 40:
                        props.create_props("bullet_box")
                    else:
                        props.create_props("medikit")
                    # 加入道具列表中
                    MainGame.props_list.append(props)
                    MainGame.mid_time = time.time()
                elif MainGame.end_time - MainGame.mid_time > MainGame.props_update_time:
                    if len(MainGame.barrier_list) != 0:
                        while True:
                            num = 0
                            # 创建道具
                            props = Props(random.randint(1, MainGame.SCREEN_WIDTH - 55), random.randint(100, MainGame.SCREEN_HEIGHT - 55))
                            for barrier in MainGame.barrier_list:
                                # 判断道具位置是否与障碍物位置重叠
                                if not pygame.sprite.collide_rect(props, barrier):
                                    num += 1
                            if num == len(MainGame.barrier_list):
                                break
                    else:
                        props = Props(random.randint(1, MainGame.SCREEN_WIDTH - 55), random.randint(100, MainGame.SCREEN_HEIGHT - 55))
                    num = random.randint(1, 100)
                    if num <= 40:
                        props.create_props("bullet_box")
                    else:
                        props.create_props("medikit")
                    # 加入道具列表中
                    MainGame.props_list.append(props)
                    MainGame.mid_time = time.time()
                else:
                    pass
            else:
                pass

    # 创建主角的方法
    @staticmethod
    def create_my():
        MainGame.me = Myself(MainGame.SCREEN_WIDTH/2, MainGame.SCREEN_HEIGHT - 100)
        MainGame.me.create("soldier")

    # 显示我方的方法
    @staticmethod
    def show_my():
        if MainGame.me.condition == "live":
            # 感知开启
            MainGame.me.warning(True)
            # 位置显示
            MainGame.me.move_display()
        else:
            pass

    # 复活我方的方法
    @staticmethod
    def relive_me():
        if MainGame.me.condition != "live":
            # 复活我方，记录次数
            MainGame.me.condition = "live"
            MainGame.me.hp = 10
            MainGame.me.rect.left = MainGame.SCREEN_WIDTH/2
            MainGame.me.rect.top = MainGame.SCREEN_HEIGHT - 55
            MainGame.fail_time += 1
            # 调用刷新显示主角生命值的方法
            Text.update_text("当前生命值剩余:{}".format(MainGame.me.hp), 5, 5)
        else:
            pass

    # 结束游戏的方法
    @staticmethod
    def end_game(flag):
        try:
            # 判断是何种方式结束游戏
            if flag == "victory":
                music = Music(r"E:\python练习\pythonProject\game\music\军事行军进行曲.wav")
                music.play()
                time.sleep(19)
            elif flag == "fail":
                pass
            elif flag == "half":
                pass
            elif flag == "other":
                pass
        finally:
            # 释放内存，关闭程序
            del MainGame.enemy_list
            del MainGame.barrier_list
            exit()


# 障碍物类
class Barrier(pygame.sprite.Sprite, object):
    def __init__(self, left, top):
        super().__init__()
        # 障碍物图片导入
        self.images = {
            "other": pygame.image.load(r"E:\python练习\pythonProject\game\image\size_normal.png"),
            "stone": pygame.image.load(r"E:\python练习\pythonProject\game\image\stone_normal.png"),
            "tree": pygame.image.load(r"E:\python练习\pythonProject\game\image\tree_normal.png"),
            "river": pygame.image.load(r"E:\python练习\pythonProject\game\image\river_normal.png"),
            "sandbag": pygame.image.load(r"E:\python练习\pythonProject\game\image\sandbag.png")
        }
        # 初始属性，位置
        self.status = "other"
        self.image = self.images["other"]
        self.rect = self.image.get_rect()
        self.rect.left = left
        self.rect.top = top
        # 判断是否可以被破坏的参数
        self.damage = "yes"
        self.condition = "live"
        self.hp = 0
        self.defend = 1
        # 远程武器通过与否
        self.across = "no"

    # 创建单个障碍物的方法
    def create(self, flag):
        self.status = flag
        if flag == "stone":
            self.image = self.images[self.status]
            self.hp = 1000
        elif flag == "tree":
            self.image = self.images[self.status]
            self.hp = 200
        elif flag == "river":
            self.image = self.images[self.status]
            self.across = "yes"
            self.damage = "no"
        elif flag == "sandbag":
            self.image = self.images[self.status]
            self.across = "yes"
            self.hp = 600
        else:
            self.status = "other"
            self.image = self.images[self.status]

    # 添加单个障碍物至窗口的方法
    def display(self):
        MainGame.window.blit(self.image, self.rect)


# 人物类
class Person(pygame.sprite.Sprite, object):
    # 动画实现所需的参数
    animation_step_1 = 0
    animation_step_2 = 0
    animation_step_3 = 0
    animation_step_4 = 0
    # 角色列表
    name_list = ["other", "soldier", "people", "ikun", "zombie"]

    def __init__(self, left, top):
        super().__init__()
        # 图片导入
        self.images = {
            "other": pygame.image.load(r"E:\python练习\pythonProject\game\image\other.png"),
            "soldier": pygame.image.load(r"E:\python练习\pythonProject\game\image\soldier_normal.png"),
            "people": pygame.image.load(r"E:\python练习\pythonProject\game\image\people_normal.png"),
            "ikun": pygame.image.load(r"E:\python练习\pythonProject\game\image\ikun_normal.png"),
            "zombie": pygame.image.load(r"E:\python练习\pythonProject\game\image\zombie_normal.png")
        }
        # 初始参数
        # 图片，初始化位置
        self.status = "other"
        self.image = self.images[self.status]
        self.rect = self.image.get_rect()
        self.rect.left = left
        self.rect.top = top
        # 状态
        self.damage = "yes"
        self.across = "no"
        self.condition = "live"
        # 生命
        self.hp = 10
        # 移速
        self.speed = 4
        # 移动状态
        self.stop = True
        self.direction = "U"
        self.step = 10
        self.move_status = [15, 25]
        # 角色位置记录(用于还原时使用)
        self.oldDirection = self.direction
        self.oldLeft = self.rect.left
        self.oldTop = self.rect.top
        # 攻击间隔
        self.attack_last_time = None
        self.attack_now_time = None
        self.attack_between_time = 2
        # 防御力
        self.defend = 5
        # 攻击力
        self.attack = 1
        # 攻击速度
        self.attack_speed = 5
        # 智能状态
        self.ai = False
        # 立场(敌对 enemy，中立 stranger，战友 friend)
        self.option = 'stranger'

    # 创建单个角色
    def create(self, flag):
        self.status = flag
        if flag == "soldier":
            self.image = self.images[self.status]
            self.attack = 10
            self.hp = 20
            self.speed = 6
            self.defend = 10
            self.attack_between_time = 0.7
            self.move_status = [25, 30]
        elif flag == "people":
            self.image = self.images[self.status]
        elif flag == "ikun":
            self.image = self.images[self.status]
            self.hp = 15
            self.speed = 6
        elif flag == "zombie":
            self.image = self.images[self.status]
            self.hp = 14
            self.speed = 1
            self.attack = 8
            self.defend = 7
            self.attack_between_time = 5
            self.move_status = [10, 15]
        else:
            self.status = "other"
            self.image = self.images[self.status]

    # 单个角色的移动方法
    def move(self):
        self.oldLeft = self.rect.left
        self.oldTop = self.rect.top
        self.oldDirection = self.direction
        if self.direction == 'L':
            if self.rect.left > 0:
                self.rect.left -= self.speed
        elif self.direction == 'R':
            if self.rect.left + self.rect.width < MainGame.SCREEN_WIDTH:
                self.rect.left += self.speed
        elif self.direction == 'U':
            if self.rect.top > 100:
                self.rect.top -= self.speed
        elif self.direction == 'D':
            if self.rect.top + self.rect.height < MainGame.SCREEN_HEIGHT - 10:
                self.rect.top += self.speed

    # 随机方向的方法
    def random_direction(self):
        num = random.randint(1, 4)
        # 判断移动方向
        if num == 1:
            self.direction = "U"
        elif num == 2:
            self.direction = "D"
        elif num == 3:
            self.direction = "R"
        elif num == 4:
            self.direction = 'L'

    # 随机移动的方法
    def random_move(self):
        if self.step <= 0:
            self.random_direction()
            self.step = random.randint(self.move_status[0], self.move_status[1])
        else:
            self.move()
            self.step -= 1

    # 保持不动的方法
    def stay(self):
        self.rect.left = self.oldLeft
        self.rect.top = self.oldTop

    # 通用障碍物碰撞检测的方法
    def collision_detection(self):
        # 遍历列表
        for target in MainGame.barrier_list:
            # 判断是否碰撞
            if pygame.sprite.collide_rect(self, target):
                self.stay()
                if self == MainGame.me:
                    # 初始字幕2刷新
                    Text.update_text("信息:{}，生命值剩余:{}".format(target.status, target.hp), 5, 80)
                elif self.status == "zombie":
                    # 僵尸会破坏建筑,判断该建筑物是否可以被破坏
                    if target.damage == "yes":
                        Person.attack(self, target)

    # 主角碰撞检测方法
    def me_crash_other(self):
        if len(MainGame.all_list) != 0:
            for item in MainGame.all_list:
                # 判断主角是否碰撞到敌方
                if pygame.sprite.collide_rect(self, item):
                    # 刷新显示敌方信息字幕方法调用
                    Text.update_text("信息:{}，生命值剩余:{}".format(item.status, item.hp), 5, 80)
                    self.stay()

    # 添加单个角色到窗口中的方法
    def display(self):
        if self.status == "people":
            # 向右移动
            if self.direction == "R" and not self.stop:
                if self.animation_step_1 <= 10:
                    MainGame.window.blit(
                        pygame.image.load(r"E:\python练习\pythonProject\game\image\people_right_run_1.png"), self.rect)
                elif 10 < self.animation_step_1 <= 20:
                    MainGame.window.blit(
                        pygame.image.load(r"E:\python练习\pythonProject\game\image\people_right_run_2.png"), self.rect)
                elif 20 < self.animation_step_1 <= 30:
                    MainGame.window.blit(
                        pygame.image.load(r"E:\python练习\pythonProject\game\image\people_right_run_mid.png"),
                        self.rect)
                elif 30 < self.animation_step_1 <= 40:
                    MainGame.window.blit(
                        pygame.image.load(r"E:\python练习\pythonProject\game\image\people_right_run_3.png"), self.rect)
                elif 40 < self.animation_step_1 <= 50:
                    MainGame.window.blit(
                        pygame.image.load(r"E:\python练习\pythonProject\game\image\people_right_run_4.png"), self.rect)
                elif 50 < self.animation_step_1 <= 60:
                    MainGame.window.blit(
                        pygame.image.load(r"E:\python练习\pythonProject\game\image\people_right_run_mid.png"),
                        self.rect)
                    if self.animation_step_1 == 60:
                        self.animation_step_1 = 1
                self.animation_step_1 += 1
            # 向左移动
            elif self.direction == "L" and not self.stop:
                if self.animation_step_2 <= 10:
                    MainGame.window.blit(
                        pygame.image.load(r"E:\python练习\pythonProject\game\image\people_left_run_1.png"), self.rect)
                elif 10 < self.animation_step_2 <= 20:
                    MainGame.window.blit(
                        pygame.image.load(r"E:\python练习\pythonProject\game\image\people_left_run_2.png"), self.rect)
                elif 20 < self.animation_step_2 <= 30:
                    MainGame.window.blit(
                        pygame.image.load(r"E:\python练习\pythonProject\game\image\people_left_run_mid.png"), self.rect)
                elif 30 < self.animation_step_2 <= 40:
                    MainGame.window.blit(
                        pygame.image.load(r"E:\python练习\pythonProject\game\image\people_left_run_3.png"), self.rect)
                elif 40 < self.animation_step_2 <= 50:
                    MainGame.window.blit(
                        pygame.image.load(r"E:\python练习\pythonProject\game\image\people_left_run_4.png"), self.rect)
                elif 50 < self.animation_step_2 <= 60:
                    MainGame.window.blit(
                        pygame.image.load(r"E:\python练习\pythonProject\game\image\people_left_run_mid.png"), self.rect)
                    if self.animation_step_2 == 60:
                        self.animation_step_2 = 1
                self.animation_step_2 += 1
            # 向下移动
            elif self.direction == "D" and not self.stop:
                if self.animation_step_3 <= 10:
                    MainGame.window.blit(self.image, self.rect)
                elif 10 < self.animation_step_3 <= 20:
                    MainGame.window.blit(
                        pygame.image.load(r"E:\python练习\pythonProject\game\image\people_normal_1.png"), self.rect)
                elif 20 < self.animation_step_3 <= 30:
                    MainGame.window.blit(self.image, self.rect)
                elif 30 < self.animation_step_3 <= 40:
                    MainGame.window.blit(
                        pygame.image.load(r"E:\python练习\pythonProject\game\image\people_normal_2.png"), self.rect)
                    if self.animation_step_3 == 40:
                        self.animation_step_3 = 1
                self.animation_step_3 += 1
            # 向上移动
            elif self.direction == "U" and not self.stop:
                if self.animation_step_4 <= 10:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_up.png"),
                                         self.rect)
                elif 10 < self.animation_step_4 <= 20:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_up_1.png"),
                                         self.rect)
                elif 20 < self.animation_step_4 <= 30:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_up.png"),
                                         self.rect)
                elif 30 < self.animation_step_4 <= 40:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_up_2.png"),
                                         self.rect)
                    if self.animation_step_4 == 40:
                        self.animation_step_4 = 1
                self.animation_step_4 += 1
            else:
                MainGame.window.blit(self.image, self.rect)
        else:
            MainGame.window.blit(self.image, self.rect)

    # 角色攻击的方法
    @staticmethod
    def attack(active_hit, passive_hit):
        flag = False
        # 判断主动攻击的对象
        if active_hit not in MainGame.bullet_list:
            # 获取攻击的时间
            active_hit.attack_now_time = time.time()
            # 攻击类型判断
            if active_hit.attack_last_time is None:
                # 第一次攻击
                flag = True
                # 判断攻击间隔是否满足
            elif active_hit.attack_now_time - active_hit.attack_last_time >= active_hit.attack_between_time:
                flag = True
            else:
                pass
        else:
            # 子弹无时间间隔限制
            flag = True
        # 判断攻击是否许可
        if flag is True:
            try:
                # 判断攻击对象
                # 角色
                if passive_hit not in MainGame.barrier_list:
                    # 判断被攻击对象是否存活
                    if passive_hit.condition == "live":
                        # 判断承受攻击者是否可以承受下此次攻击
                        if passive_hit.hp > active_hit.attack / passive_hit.defend:
                            passive_hit.hp = passive_hit.hp - active_hit.attack / passive_hit.defend
                            passive_hit.music_play("hurt")
                            Person.action_play(passive_hit, passive_hit.status, "hurt")
                        else:
                            passive_hit.condition = "die"
                            passive_hit.hp = 0
                            passive_hit.music_play("die")
                            Person.action_play(passive_hit, passive_hit.status, "die")
                    # 判断是否为主角攻击(需为近距离攻击才有效)
                    if active_hit == MainGame.me:
                        if passive_hit.option == "stranger":
                            # 改变立场
                            passive_hit.option = "enemy"
                            MainGame.stranger_list.remove(passive_hit)
                            MainGame.enemy_list.append(passive_hit)
                            # 复仇反击
                            passive_hit.ai = True
                        elif passive_hit.option == "enemy":
                            if not passive_hit.ai:
                                passive_hit.ai = True
                        else:
                            pass
                else:
                    # 建筑物
                    if passive_hit.condition == "live":
                        # 判断承受攻击者是否可以承受下此次攻击
                        if passive_hit.hp > active_hit.attack / passive_hit.defend:
                            passive_hit.hp = passive_hit.hp - active_hit.attack / passive_hit.defend
                            music = Music(r"E:\python练习\pythonProject\game\music\游戏碰撞音效.wav")
                            music.play()
                        else:
                            passive_hit.hp = 0
                            passive_hit.condition = "die"
                            music = Music(r"E:\python练习\pythonProject\game\music\房屋倒塌声.flac")
                            music.play()
            finally:
                active_hit.attack_last_time = time.time()
                pass

    # 角色生命值减少时的音效方法
    def music_play(self, flag):
        # 判断角色
        if self != MainGame.me:
            if self.status == "people" or self.status == "soldier":
                if flag == "hurt":
                    music = Music(r"E:\python练习\pythonProject\game\music\男性受伤噢一声.mp3")
                    music.play()
                elif flag == "die":
                    music = Music(r"E:\python练习\pythonProject\game\music\男性死亡音效.mp3")
                    music.play()
            elif self.status == "zombie":
                if flag == "hurt":
                    music = Music(r"E:\python练习\pythonProject\game\music\僵尸咆哮_丧尸攻击.mp3")
                    music.play()
                elif flag == "die":
                    music = Music(r"E:\python练习\pythonProject\game\music\简单的死亡声音.wav")
                    music.play()
            else:
                pass
        else:
            if flag == "hurt":
                music = Music(r"E:\python练习\pythonProject\game\music\男性受伤噢一声.wav")
                music.blend_play(0.4)
            elif flag == "die":
                music = Music(r"E:\python练习\pythonProject\game\music\男人痛苦的叫声homo.mp3")
                music.blend_play(0.6)
            else:
                pass

    # 角色动作动画的方法
    @staticmethod
    def action_play(person, name, flag):
        # 判断角色
        if name == "people" or name == "soldier":
            # 判断方法
            if flag == "hurt":
                for i in range(30):
                    if i <= 10:
                        MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_hurt_1.png"), (person.rect.left, person.rect.top))
                    elif 10 < i <= 20:
                        MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_hurt_2.png"), (person.rect.left, person.rect.top))
                    elif 20 < i <= 30:
                        MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_hurt_3.png"), (person.rect.left, person.rect.top))
            elif flag == "attack":
                pass
            elif flag == "die":
                for i in range(100):
                    if i <= 10:
                        MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_die_1.png"), (person.rect.left, person.rect.top))
                    elif 10 < i <= 20:
                        MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_die_2.png"), (person.rect.left, person.rect.top))
                    elif 20 < i <= 30:
                        MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_die_3.png"), (person.rect.left, person.rect.top))
                    elif 30 < i <= 40:
                        MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_die_4.png"), (person.rect.left, person.rect.top))
                    elif 40 < i <= 50:
                        MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_die_5.png"), (person.rect.left, person.rect.top))
                    elif 50 < i <= 60:
                        MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_die_6.png"), (person.rect.left, person.rect.top))
                    elif 60 < i <= 70:
                        MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_die_7.png"), (person.rect.left, person.rect.top))
                    elif 70 < i <= 80:
                        MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_die_8.png"), (person.rect.left, person.rect.top))
                    elif 80 < i <= 90:
                        MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_die_9.png"), (person.rect.left, person.rect.top))
                    elif 90 < i <= 100:
                        MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_die_9.png"), (person.rect.left, person.rect.top))
        elif name == "zombie":
            if flag == "die":
                for i in range(60):
                    if i <= 10:
                        MainGame.window.blit(
                            pygame.image.load(r"E:\python练习\pythonProject\game\image\zombie_die_1.png"),
                            (person.rect.left, person.rect.top))
                    elif 10 < i <= 20:
                        MainGame.window.blit(
                            pygame.image.load(r"E:\python练习\pythonProject\game\image\zombie_die_2.png"),
                            (person.rect.left, person.rect.top))
                    elif 20 < i <= 30:
                        MainGame.window.blit(
                            pygame.image.load(r"E:\python练习\pythonProject\game\image\zombie_die_3.png"),
                            (person.rect.left, person.rect.top))
                    elif 30 < i <= 40:
                        MainGame.window.blit(
                            pygame.image.load(r"E:\python练习\pythonProject\game\image\zombie_die_4.png"),
                            (person.rect.left, person.rect.top))
                    elif 40 < i <= 50:
                        MainGame.window.blit(
                            pygame.image.load(r"E:\python练习\pythonProject\game\image\zombie_die_5.png"),
                            (person.rect.left, person.rect.top))
                    elif 50 < i <= 60:
                        MainGame.window.blit(
                            pygame.image.load(r"E:\python练习\pythonProject\game\image\zombie_die_5.png"),
                            (person.rect.left, person.rect.top))
            else:
                pass
        else:
            pass


# 主角类
class Myself(Person):
    # 动画实现所需的参数
    animation_step_1 = 0
    animation_step_2 = 0
    animation_step_3 = 0
    animation_step_4 = 0
    # 动画播放参数，使动画随着速度的提升而加快
    step_speed = 0
    # 主角攻击距离
    attack_long = 10

    def __init__(self, left, top):
        super().__init__(left, top)
        # 主角感知距离
        self.feel_long = 150
        self.feel_last_time = None
        self.feel_now_time = None
        self.feel_between_time = 10

    # 角色移动动画的方法
    def move_display(self):
        self.step_speed = MainGame.MAX_SPEED - self.speed
        if self.status == "people":
            # 向右移动
            if self.direction == "R" and not self.stop:
                if self.animation_step_1 <= self.step_speed * 1:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_right_run_1.png"), self.rect)
                elif self.step_speed * 1 < self.animation_step_1 <= self.step_speed * 2:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_right_run_2.png"), self.rect)
                elif self.step_speed * 2 < self.animation_step_1 <= self.step_speed * 3:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_right_run_mid.png"), self.rect)
                elif self.step_speed * 3 < self.animation_step_1 <= self.step_speed * 4:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_right_run_3.png"), self.rect)
                elif self.step_speed * 4 < self.animation_step_1 <= self.step_speed * 5:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_right_run_4.png"), self.rect)
                elif self.step_speed * 5 < self.animation_step_1 <= self.step_speed * 6:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_right_run_mid.png"), self.rect)
                    if self.animation_step_1 == self.step_speed * 6:
                        self.animation_step_1 = 1
                self.animation_step_1 += 1
            # 向左移动
            elif self.direction == "L" and not self.stop:
                if self.animation_step_2 <= self.step_speed * 1:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_left_run_1.png"), self.rect)
                elif self.step_speed * 1 < self.animation_step_2 <= self.step_speed * 2:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_left_run_2.png"), self.rect)
                elif self.step_speed * 2 < self.animation_step_2 <= self.step_speed * 3:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_left_run_mid.png"), self.rect)
                elif self.step_speed * 3 < self.animation_step_2 <= self.step_speed * 4:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_left_run_3.png"), self.rect)
                elif self.step_speed * 4 < self.animation_step_2 <= self.step_speed * 5:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_left_run_4.png"), self.rect)
                elif self.step_speed * 5 < self.animation_step_2 <= self.step_speed * 6:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_left_run_mid.png"), self.rect)
                    if self.animation_step_2 == self.step_speed * 6:
                        self.animation_step_2 = 1
                self.animation_step_2 += 1
            # 向下移动
            elif self.direction == "D" and not self.stop:
                if self.animation_step_3 <= self.step_speed * 1:
                    MainGame.window.blit(self.image, self.rect)
                elif self.step_speed * 1 < self.animation_step_3 <= self.step_speed * 2:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_normal_1.png"), self.rect)
                elif self.step_speed * 2 < self.animation_step_3 <= self.step_speed * 3:
                    MainGame.window.blit(self.image, self.rect)
                elif self.step_speed * 3 < self.animation_step_3 <= self.step_speed * 4:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_normal_2.png"), self.rect)
                    if self.animation_step_3 == self.step_speed * 4:
                        self.animation_step_3 = 1
                self.animation_step_3 += 1
            # 向上移动
            elif self.direction == "U" and not self.stop:
                if self.animation_step_4 <= self.step_speed * 1:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_up.png"), self.rect)
                elif self.step_speed * 1 < self.animation_step_4 <= self.step_speed * 2:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_up_1.png"), self.rect)
                elif self.step_speed * 2 < self.animation_step_4 <= self.step_speed * 3:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_up.png"), self.rect)
                elif self.step_speed * 3 < self.animation_step_4 <= self.step_speed * 4:
                    MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\people_up_2.png"), self.rect)
                    if self.animation_step_4 == self.step_speed * 4:
                        self.animation_step_4 = 1
                self.animation_step_4 += 1
            else:
                MainGame.window.blit(self.image, self.rect)
        elif self.status == "soldier":
            if self.direction == "R" and not self.stop:
                MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\soldier_right.png"), self.rect)
            elif self.direction == "L" and not self.stop:
                MainGame.window.blit(pygame.image.load(r"E:\python练习\pythonProject\game\image\soldier_left.png"), self.rect)
            else:
                MainGame.window.blit(self.image, self.rect)
        else:
            MainGame.window.blit(self.image, self.rect)

    # 怪物接近提示
    def warning(self, sign):
        # 判断提示是否开启
        if sign is True:
            # 警告的指标
            flag = False
            # 获取时间
            self.feel_now_time = time.time()
            # 判断时间间隔
            if self.feel_last_time is None:
                flag = True
                self.feel_last_time = self.feel_now_time
            elif self.feel_now_time - self.feel_last_time > self.feel_between_time:
                flag = True
                self.feel_last_time = self.feel_now_time
            else:
                pass
            if flag is True:
                # 判断列表非空
                if MainGame.enemy_list:
                    for enemy in MainGame.enemy_list:
                        # 判断距离
                        if self.rect.left - self.feel_long <= enemy.rect.left + 27 <= self.rect.left + 54 + self.feel_long:
                            if self.rect.top - self.feel_long <= enemy.rect.top + 27 <= self.rect.top + 54 + self.feel_long:
                                # 未接触
                                if not pygame.sprite.collide_rect(self, enemy):
                                    # 判断种类  采用混音播放的方法
                                    if enemy.status == "zombie":
                                        music = Music(r"E:\python练习\pythonProject\game\music\丧尸怒吼大叫.wav")
                                        music.blend_play(0.1)
                                    elif enemy.status == "soldier":
                                        music = Music(r"E:\python练习\pythonProject\game\music\士兵的喊叫怒吼.flac")
                                        music.blend_play(0.2)
                                    elif enemy.status == "people":
                                        music = Music(r"E:\python练习\pythonProject\game\music\男人匆忙的叫喊.mp3")
                                        music.blend_play(0.2)
                                    else:
                                        music = Music(r"E:\python练习\pythonProject\game\music\游戏警报音效.wav")
                                        music.blend_play(0.2)

    # 角色攻击的方法
    @staticmethod
    def attack_display():
        # 判断当前角色身份
        if MainGame.me.status == "people":
            if MainGame.all_list:
                for item in MainGame.all_list:
                    # 判断当前朝向
                    # 向右
                    if MainGame.me.direction == "R":
                        # 判断 top 坐标上
                        if MainGame.me.rect.top <= item.rect.top + 27 <= MainGame.me.rect.top + 54:
                            # 判断 left 坐标上
                            if MainGame.me.rect.left + 54 <= item.rect.left <= MainGame.me.rect.left + 54 + MainGame.me.attack_long:
                                # 调用攻击方法
                                Person.attack(MainGame.me, item)
                    elif MainGame.me.direction == "L":
                        # 判断 top 坐标上
                        if MainGame.me.rect.top <= item.rect.top + 27 <= MainGame.me.rect.top + 54:
                            # 判断 left 坐标上
                            if MainGame.me.rect.left - MainGame.me.attack_long <= item.rect.left + 54 <= MainGame.me.rect.left:
                                # 调用攻击方法
                                Person.attack(MainGame.me, item)
                    elif MainGame.me.direction == "U":
                        # 判断 top 坐标上
                        if MainGame.me.rect.top <= item.rect.top + 54 <= MainGame.me.rect.top + MainGame.me.attack_long:
                            # 判断 left 坐标上
                            if MainGame.me.rect.left <= item.rect.left + 27 <= MainGame.me.rect.left + 54:
                                # 调用攻击方法
                                Person.attack(MainGame.me, item)
                    elif MainGame.me.direction == "D":
                        # 判断 top 坐标上
                        if MainGame.me.rect.top + 54 <= item.rect.top <= MainGame.me.rect.top + 54 + MainGame.me.attack_long:
                            # 判断 left 坐标上
                            if MainGame.me.rect.left <= item.rect.left + 27 <= MainGame.me.rect.left + 54:
                                # 调用攻击方法
                                Person.attack(MainGame.me, item)
                    else:
                        pass
        elif MainGame.me.status == "soldier":
            # 判断子弹是否足够
            if MainGame.bullet_number >= 1:
                # 调用开枪的方法
                Animation.shot(MainGame.me)
                MainGame.bullet_number -= 1
            else:
                if MainGame.all_list:
                    for item in MainGame.all_list:
                        # 判断当前朝向
                        # 向右
                        if MainGame.me.direction == "R":
                            # 判断 top 坐标上
                            if MainGame.me.rect.top <= item.rect.top + 27 <= MainGame.me.rect.top + 54:
                                # 判断 left 坐标上
                                if MainGame.me.rect.left + 54 <= item.rect.left <= MainGame.me.rect.left + 54 + MainGame.me.attack_long:
                                    # 调用攻击方法
                                    Person.attack(MainGame.me, item)
                        elif MainGame.me.direction == "L":
                            # 判断 top 坐标上
                            if MainGame.me.rect.top <= item.rect.top + 27 <= MainGame.me.rect.top + 54:
                                # 判断 left 坐标上
                                if MainGame.me.rect.left - MainGame.me.attack_long <= item.rect.left + 54 <= MainGame.me.rect.left:
                                    # 调用攻击方法
                                    Person.attack(MainGame.me, item)
                        elif MainGame.me.direction == "U":
                            # 判断 top 坐标上
                            if MainGame.me.rect.top <= item.rect.top + 54 <= MainGame.me.rect.top + MainGame.me.attack_long:
                                # 判断 left 坐标上
                                if MainGame.me.rect.left <= item.rect.left + 27 <= MainGame.me.rect.left + 54:
                                    # 调用攻击方法
                                    Person.attack(MainGame.me, item)
                        elif MainGame.me.direction == "D":
                            # 判断 top 坐标上
                            if MainGame.me.rect.top + 54 <= item.rect.top <= MainGame.me.rect.top + 54 + MainGame.me.attack_long:
                                # 判断 left 坐标上
                                if MainGame.me.rect.left <= item.rect.left + 27 <= MainGame.me.rect.left + 54:
                                    # 调用攻击方法
                                    Person.attack(MainGame.me, item)
                        else:
                            pass
        else:
            pass

    # 角色获取道具检测
    @staticmethod
    def get_props():
        # 判断道具列表非空
        if MainGame.props_list:
            for props in MainGame.props_list:
                # 判断是否接触
                if pygame.sprite.collide_rect(MainGame.me, props):
                    # 播放音效
                    music = Music(r"E:\python练习\pythonProject\game\music\游戏拾取物品音效.wav")
                    music.blend_play(0.8)
                    # 调用道具类中获得单个道具时的对应方法
                    props.get_props()
                else:
                    pass


# 字幕类
class Text(object):
    def __init__(self, left, top):
        super().__init__()
        self.left = left
        self.top = top
        self.text = None

    # 默认字幕(基本内容)
    @staticmethod
    def base_text():
        # 初始字幕1
        Text.create_data("当前生命值剩余:{}".format(MainGame.me.hp), 5, 5)
        # 初始字幕2
        Text.create_data("当前敌对角色剩余:{}".format(len(MainGame.enemy_list)), 5, 30)
        # 初始字幕3
        Text.create_data("当前子弹剩余:{}".format(MainGame.bullet_number), 5, 55)
        # 初始字幕4
        if True:
            status = ""
            hp = ""
            item = "信息:{}，生命值剩余:{}".format(status, hp)
            Text.create_data(item, 5, 80)

    # 创建字幕的方法
    @staticmethod
    def create_data(text, left, top):
        # 判断字幕列表非空
        if len(MainGame.text_list) != 0:
            for item in MainGame.text_list:
                # 判断是否重复
                if item.left == left and item.top == top:
                    pass
                else:
                    # 创建字幕并添加至字幕列表中
                    text_surface = Text(left, top)
                    text_surface.text = text
                    MainGame.text_list.append(text_surface)
        else:
            # 创建字幕并添加至字幕列表中
            text_surface = Text(left, top)
            text_surface.text = text
            MainGame.text_list.append(text_surface)

    # 更新单个字幕的方法
    @staticmethod
    def update_text(text, left, top):
        # 用于判断是否刷新的参数
        flag = True  # 刷新限制已关闭
        MainGame.now_apply_time = time.time()
        # 判断刷新时间
        if MainGame.last_apply_time is None:
            flag = True
            MainGame.last_apply_time = MainGame.now_apply_time
        elif MainGame.now_apply_time - MainGame.last_apply_time >= MainGame.update_output_time:
            MainGame.last_apply_time = MainGame.now_apply_time
            flag = True
        if flag is True:
            # 判断字幕列表非空
            if len(MainGame.text_list):
                for item in MainGame.text_list:
                    # 判断更新位置
                    if item.left == left and item.top == top:
                        item.text = text
                    else:
                        pass

    # 展示字幕的方法
    @staticmethod
    def blit_text():
        # 初始化字体模块
        pygame.font.init()
        # 选中合适的字体
        font = pygame.font.SysFont('kaiti', 20)
        # 使用相应的字符完成相关的内容绘制
        for text_surface in MainGame.text_list:
            sentence = font.render(text_surface.text, True, [255, 0, 0])
            # 判断内容非空
            if text_surface.text:
                # 生成字幕
                MainGame.window.blit(sentence, [text_surface.left, text_surface.top])


# 道具类
class Props(Person):
    def __init__(self, left, top):
        super().__init__(left, top)
        self.images = {
            "other": pygame.image.load(r"E:\python练习\pythonProject\game\image\other.png"),
            "bullet_box": pygame.image.load(r"E:\python练习\pythonProject\game\image\bullet_box.png"),
            "medikit": pygame.image.load(r"E:\python练习\pythonProject\game\image\medikit.png"),
        }
        self.status = "other"
        self.image = self.images[self.status]
        self.rect = self.image.get_rect()
        self.rect.left = left
        self.rect.top = top
        self.damage = "no"
        self.condition = "live"
        self.across = "yes"
        # 道具效果
        self.effect = None

    # 创建单个道具的方法
    def create_props(self, flag):
        self.status = flag
        # 弹药箱
        if flag == "bullet_box":
            self.image = self.images[self.status]
            self.effect = "bullet"
        # 医疗箱
        elif flag == "medikit":
            self.image = self.images[self.status]
            self.effect = "cure"
        else:
            pass

    # 获得单个道具时的对应方法
    def get_props(self):
        # 判断道具状态
        if self.condition == "live":
            # 判断道具类型
            try:
                if self.status == "bullet_box":
                    MainGame.bullet_number += 20
                elif self.status == "medikit":
                    MainGame.me.hp += 5
                else:
                    pass
            finally:
                # 改变道具状态
                self.condition = "die"


# 特效类
class Animation(pygame.sprite.Sprite, object):
    def __init__(self, left, top):
        super().__init__()
        self.images = {
            "other": pygame.image.load(r"E:\python练习\pythonProject\game\image\size_normal.png"),
            "bullet": pygame.image.load(r"E:\python练习\pythonProject\game\image\bullet.png"),

        }
        self.status = "other"
        self.image = self.images[self.status]
        self.direction = "U"
        self.rect = self.image.get_rect()
        self.rect.left = left
        self.rect.top = top
        self.condition = "live"
        self.speed = 1
        self.attack = 0

    # 开枪的方法
    @staticmethod
    def shot(who):
        # 判断角色身份
        if who.status == "soldier":
            music = Music(r"E:\python练习\pythonProject\game\music\枪声（手枪).wav")
            music.blend_play(0.5)
            bullet = Animation(who.rect.left, who.rect.top)
            bullet.speed = 20
            bullet.attack = 23
            # 获得开枪方向
            bullet.direction = who.direction
            bullet.status = "bullet"
            bullet.image = bullet.images[bullet.status]
            MainGame.window.blit(bullet.image, bullet.rect)
            # 获得精确射击位置
            if who.direction == "R":
                bullet.rect.left = who.rect.left + 54
                bullet.rect.top = who.rect.top + 27
            elif who.direction == "L":
                bullet.rect.left = who.rect.left
                bullet.rect.top = who.rect.top + 27
            elif who.direction == "U":
                bullet.rect.left = who.rect.left + 27
                bullet.rect.top = who.rect.top
            elif who.direction == "D":
                bullet.rect.left = who.rect.left + 27
                bullet.rect.top = who.rect.top + 54
            # 添加到子弹列表中
            MainGame.bullet_list.append(bullet)

    # 子弹碰撞及伤害计算的方法
    @staticmethod
    def bullet_hit():
        # 判断全列表非空
        if len(MainGame.all_list) != 0 and len(MainGame.bullet_list) != 0:
            for bullet in MainGame.bullet_list:
                for item in MainGame.all_list:
                    # 判断是否可以穿过
                    if item.across == "no":
                        # 判断是否可以破坏
                        if item.damage == "yes":
                            # 判断是否碰撞
                            if pygame.sprite.collide_rect(bullet, item):
                                # 判断是否能够承受此次攻击
                                if item.hp > bullet.attack / item.defend:
                                    item.hp -= bullet.attack / item.defend
                                    if item not in MainGame.barrier_list:
                                        item.music_play("hurt")
                                        Person.action_play(item, item.status, "hurt")
                                    elif item.status == "stone" or item.status == "sandbag":
                                        music = Music(r"E:\python练习\pythonProject\game\music\游戏碰撞音效.wav")
                                        music.play()
                                    else:
                                        music = Music(r"E:\python练习\pythonProject\game\music\游戏碰撞音效.wav")
                                        music.play()
                                else:
                                    item.condition = "die"
                                    item.hp = 0
                                    if item not in MainGame.barrier_list:
                                        item.music_play("die")
                                        Person.action_play(item, item.status, "die")
                                    elif item.status == "stone" or item.status == "sandbag":
                                        music = Music(r"E:\python练习\pythonProject\game\music\房屋倒塌声.flac")
                                        music.play()
                                    else:
                                        music = Music(r"E:\python练习\pythonProject\game\music\房屋倒塌声.flac")
                                        music.play()
                                bullet.condition = "die"
                            else:
                                pass
                        else:
                            pass
                    else:
                        pass

    # 子弹的更新以及处理
    @staticmethod
    def update_bullet():
        Animation.bullet_hit()
        if MainGame.bullet_list:
            for bullet in MainGame.bullet_list:
                if bullet.condition == "live":
                    if bullet.direction == "R":
                        bullet.rect.left += bullet.speed
                    elif bullet.direction == "L":
                        bullet.rect.left -= bullet.speed
                    elif bullet.direction == "U":
                        bullet.rect.top -= bullet.speed
                    elif bullet.direction == "D":
                        bullet.rect.top += bullet.speed
                else:
                    MainGame.bullet_list.remove(bullet)
                MainGame.window.blit(bullet.image, bullet.rect)


# 音效类  完成
class Music(object):
    def __init__(self, fileName):
        self.fileName = fileName
        # 先初始化混响器
        pygame.mixer.init()
        # 获取指定文件的位置
        pygame.mixer.music.load(self.fileName)

    # 混音播放的方法
    def blend_play(self, size):
        music = pygame.mixer.Sound(self.fileName)
        if 0 <= size <= 1:
            music.set_volume(size)
        else:
            music.set_volume(0.5)
        music.play()

    # 播放音乐的方法
    @staticmethod
    def play():
        pygame.mixer.music.set_volume(0.5)
        pygame.mixer.music.play(loops=0)

    # 游戏开始背景音乐播放
    @staticmethod
    def background_music_start():
        pygame.mixer.init()
        music = pygame.mixer.Sound(r"E:\python练习\pythonProject\game\music\战争与和平.flac")
        music.set_volume(0.7)
        music.play()

    # 游戏循环播放音效
    @staticmethod
    def background_music():
        pygame.mixer.init()
        music = pygame.mixer.Sound(r"E:\python练习\pythonProject\game\music\城市雨声.mp3")
        music.set_volume(0.7)
        music.play()


# AI类
class Ai_function(object):
    def __init__(self):
        super().__init__()
        pass

    # 自动寻路的方法（存在缺陷，寻路过程持续抖动）
    @staticmethod
    def ai_way_to_other(begin, target):
        # 判断智能状态
        if begin.ai is True:
            # 判断目标是否存在
            if target.condition == "live":
                width = begin.rect.left - target.rect.left
                height = begin.rect.top - target.rect.top
                # 随机靠近方向
                num = random.randint(1, 100)
                if num <= 50:
                    if width <= 0:
                        begin.direction = "R"
                        begin.move()
                    else:
                        begin.direction = "L"
                        begin.move()
                else:
                    if height <= 0:
                        begin.direction = "D"
                        begin.move()
                    else:
                        begin.direction = "U"
                        begin.move()
            else:
                begin.random_move()
        else:
            begin.random_move()

    # 自动寻路改进方案  暂未完成
    @staticmethod
    def ai_way_to_other_data(begin, target):
        # 判断寻路目标状态状态
        if begin.ai is True:
            # 判断被搜索目标状态
            if target.conditon == "live":
                # 计算想换参数
                width = begin.rect.left - target.rect.left
                height = begin.rect.top - target.rect.top
                # 以一定路径靠近目标(优先水平方向上的靠近)
                # 进行水平方向上的判断
                if width != 0:
                    # 判断在寻路目标水平方向上的位置
                    if width > 0:
                        begin.direction = "L"
                        begin.move()
                    else:
                        begin.direction = "R"
                        begin.move()
                elif height != 0:
                    # 判断在寻路目标竖直方向上的位置
                    if height > 0:
                        begin.direction = "U"
                        begin.move()
                    else:
                        begin.direction = "D"
                        begin.move()


# 启动游戏
MainGame().start_game()
